import datetime
import os
import platform
import smtplib
import stat
import tarfile

class backupJob:
	"""Classe de generation d'une sauvegarde.
	"""
	
	def __init__(self, message, backupName, initialFolder, destinationFolder, retentionDuration=30):
		"""Initialisation du systeme.
		"""
		self._backupName = backupName
		self._message = message
		self._initialFolder = initialFolder
		self._destinationFolder = destinationFolder
		self._retention = retentionDuration
		# Initialisation pour le systeme.
		self._platform = platform.system().upper()
	
	def generateFileName(self,):
		"""Generation du nom du fichier de sauvegarde.
		"""
		today = datetime.date.today()
		if "WINDOWS" == self._platform:
			fileName = self._destinationFolder + "\\%d-%02d-%02d.tar.gz"%(today.year, today.month, today.day,)
		else:
			fileName = self._destinationFolder + "/%d-%02d-%02d.tar.gz"%(today.year, today.month, today.day,)
		return fileName
	
	def generateTar(self, fileName,):
		"""Generation du fichier de tar.
		"""
		nbFiles = 0
		sizeFiles = 0
		if os.path.exists(fileName):
			# Si le fichier existe deja, on ne le fabrique pas a nouveau.
			self._message.write(" {"+self._backupName+"} FICHIER TAR DEJA PRESENT")
			return
		try:
			tar = tarfile.open(fileName, 'w:gz')
			for root, dirs, files in os.walk(self._initialFolder):
				for f in files:
					if "WINDOWS" == self._platform:
						# currFileName = root + "\\" + f
						currFileName = unicode(root + "\\" + f, "cp1252", errors="replace").replace("?", "_")
					else:
						currFileName = unicode(root + "/" + f, "utf8")
					#print currFileName
					try:
						tar.add(currFileName)
						# Mise a jour des donnees statistiques.
						nbFiles += 1
						#sizeFiles += os.path.getsize(currFileName)
					except Exception, err:
						self._message.write(" {"+self._backupName+"} Erreur d'insertion d'un fichier: "+str(err))
			tar.close()
		except Exception, err:
			self._message.write(" {"+self._backupName+"} Erreur de generation du fichier TAR: "+str(err))
			return
		self._message.write(" {"+self._backupName+"} Fin de l'archivage des fichiers")
		self._message.write(" {"+self._backupName+"} Nombre de fichiers: %d"%nbFiles)
		#self._message.write(" {"+self._backupName+"} Taille total : %d"%sizeFiles)
	
	def prune(self,):
		"""Effectue le nettoyage des anciens fichiers.
		"""
		if self._retention < 15:
			self._message.write(" {"+self._bakupName+"} ERREUR IRRECUPERABLE: Le delai de conservation est < 15jours, aucune suppression n'est faite")
			return
		self._message.write(" {"+self._backupName+"} Nettoyage des fichiers plus anciens que %d jours"%self._retention)
		listArchives = [f for f in os.listdir(self._destinationFolder) if f.endswith(".tar.gz")]
		today = datetime.datetime.today()
		toKeep = list()
		toDelete = list()
		# Tri des fichiers d'archives.
		for fileName in listArchives:
			fullName = fileName.split(".")[0]
			fullFileName = self._destinationFolder + "\\" + fileName
			fileDateStr = fullName.split("-")
			if 3 == len(fileDateStr):
				try:
					lastModif = datetime.datetime(int(fileDateStr[0]), int(fileDateStr[1]), int(fileDateStr[2]))
					diffDate = today - lastModif
					if diffDate.days < self._retention:
						toKeep.append(fullFileName)
					else:
						toDelete.append(fullFileName)
				except:
					pass
		# Operations.
		self._message.write(" {"+self._backupName+"} Bilan des sauvegardes")
		if 0 == len(toKeep):
			self._message.write(" {"+self._backupName+"} Aucune sauvegarde a conserver")
		else:
			self._message.write(" {"+self._backupName+"} Nombre de sauvegardes en conservation: %d"%len(toKeep))
			for fName in toKeep:
				self._message.write(" {"+self._backupName+"} Archive: %s"%fName)
		if 0 == len(toDelete):
			self._message.write(" {"+self._backupName+"} Aucune sauvegarde a detruire")
		else:
			self._message.write(" {"+self._backupName+"} Nombre de sauvegardes a detruire: %d"%len(toDelete))
			for fName in toDelete:
				self._message.write(" {"+self._backupName+"} Archive %s detruite"%fName)
				os.remove( fName)
	
	def run(self,):
		"""Lancement de la sauvegarde.
		"""
		# Validation des parametres transmis.
		if "" == self._initialFolder or "" == self._destinationFolder:
			self._message.write(" {"+self._backupName+"} ERREUR GRAVE: Un des dossiers de configuration est vide.")
			return
		fileName = self.generateFileName()
		self._message.write(" {"+self._backupName+"} Nom du fichier: "+fileName)
		self._message.write(" {"+self._backupName+"} Lancement de l'archivage des fichiers ...")
		self.generateTar(fileName)
		self._message.write(" {"+self._backupName+"} Fin de l'archivage des fichiers")
		self._message.write(" {"+self._backupName+"} Lancement du nettoyage des anciens fichiers ...")
		self.prune()
		self._message.write(" {"+self._backupName+"} Fin du nettoyage")
